package com.itlaoqi.cf.controller;

import com.itlaoqi.cf.dto.Member;
import com.itlaoqi.cf.dto.Order;
import com.itlaoqi.cf.dto.Product;
import com.itlaoqi.cf.service.MemberService;
import com.itlaoqi.cf.service.OrderService;
import com.itlaoqi.cf.service.ProductService;
import lombok.SneakyThrows;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class PortalController {
    //串行化
    public void case1() throws ExecutionException, InterruptedException {
        Long startTime = System.currentTimeMillis();
        MemberService memberService = new MemberService();
        OrderService orderService = new OrderService();
        ProductService productService = new ProductService();
        Map<String, Member> r1 = memberService.search();
        System.out.println(r1);
        List<Order> r2 = orderService.search();
        System.out.println(r2);
        List<Product> r3 = productService.search();
        System.out.println(r3);
        Long endTime = System.currentTimeMillis();
        System.out.println("Total time: " + (endTime - startTime) + "ms");
    }

    //全并行化
    public void case2() throws ExecutionException, InterruptedException {
        Long startTime = System.currentTimeMillis();
        MemberService memberService = new MemberService();
        OrderService orderService = new OrderService();
        ProductService productService = new ProductService();

        CompletableFuture<Map<String, Member>> memberFuture = CompletableFuture.supplyAsync(()->memberService.search());
        CompletableFuture<List<Order>> orderFuture = CompletableFuture.supplyAsync(()->orderService.search());
        CompletableFuture<List<Product>> productFuture = CompletableFuture.supplyAsync(()->productService.search());
        CompletableFuture.allOf(memberFuture, orderFuture, productFuture);

        System.out.println(memberFuture.get());
        System.out.println(orderFuture.get());
        System.out.println(productFuture.get());
        Long endTime = System.currentTimeMillis();
        System.out.println("Total time: " + (endTime - startTime) + "ms");
    }


    //任务编排
    /*
         A
        /\
       B  C
     */
    @SneakyThrows
    public void case3()  {
        Long startTime = System.currentTimeMillis();
        MemberService memberService = new MemberService();
        OrderService orderService = new OrderService();
        ProductService productService = new ProductService();
        //返回处理完成的任务，这里会产生阻塞
        CompletableFuture<Map<String, Member>> memberFuture = CompletableFuture.completedFuture(memberService.search());
        //得到结果
        System.out.println(memberFuture.get());
        //后续两个任务并行化
        CompletableFuture<List<Order>> orderFuture = CompletableFuture.supplyAsync(()->orderService.search());
        CompletableFuture<List<Product>> productFuture = CompletableFuture.supplyAsync(()->productService.search());
        CompletableFuture.allOf(orderFuture, productFuture);

        System.out.println(orderFuture.get());
        System.out.println(productFuture.get());
        Long endTime = System.currentTimeMillis();
        System.out.println("Total time: " + (endTime - startTime) + "ms");

    }

    //利用事件机制实现复杂编排
    /*
        A  B
           C
        完成
     */
    @SneakyThrows
    public void case4()  {
        Long startTime = System.currentTimeMillis();
        MemberService memberService = new MemberService();
        OrderService orderService = new OrderService();
        ProductService productService = new ProductService();
        //返回处理完成的任务，这里会产生阻塞
        CompletableFuture<Map<String, Member>> memberFuture = CompletableFuture.supplyAsync(()->memberService.search());
        CompletableFuture<List<Product>> productFuture = CompletableFuture.supplyAsync(() -> productService.search());

        CompletableFuture<List<Order>> orderFuture = productFuture.thenApply((products) -> {
            return orderService.search();
        });
        CompletableFuture.allOf(memberFuture, orderFuture);
        //实现编排
        System.out.println(memberFuture.get());
        System.out.println(productFuture.get());
        System.out.println(orderFuture.get());
        Long endTime = System.currentTimeMillis();
        System.out.println("Total time: " + (endTime - startTime) + "ms");

    }

}
